/**
 * Application-level middleware  The function is executed every time the app receives a request with no mount path,
 * or handle some request with the request mapping.
 * Created by hjqi on 2016/1/11.
 */
var express = require('express');
var path = require('path');
var logger = require('morgan');
var log4js = require('log4js');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var timeout = require('connect-timeout');
var conf = require('./lib/config/config').config;
var compression = require('compression');
/**
 * fork a process
 */
const fs = require('fs');
const child_process = require('child_process');
// var workerProcess = child_process.spawn('node',[ './lib/child_process/sub_process.js']  ); //support
var debug = typeof v8debug === 'object';
if (debug) {
    //Set an unused port number.
    process.execArgv.push('--debug=' + (40894));
}
// var workerProcess = child_process.fork(__dirname + '/task.js');

var workerProcess = child_process.fork(path.join(__dirname,'./lib/child_process/sub_process.js')); //support
//mongodb
//it will join
var monk = require('monk');
var db = monk(conf.mongodb.url, conf.mongodb.opts);
var util = require('util');
//jwt
var _jwt = require('jsonwebtoken');

global.ROLE = {
    DEVELOPER: "开发人员",
    QAER: "测试人员",
    OPERATOR: "运维人员"
}

global.ENVIRONMENT = {
    QA: "testenv",
    PROD: "prod"
}

var app = express();
var log4jsLogger =  require('./lib/log4js/log4js').logger('server.js');
app.use(log4js.connectLogger(log4jsLogger));
var reqTimeout = conf.requestTimeout || 30000;
app.use(timeout(reqTimeout));
app.use(function (req, res, next){
    if (!req.timedout) next();
});


function startProcess()  {

    workerProcess.stdout.on('data', function (data) {
         log4jsLogger.info('receive standard output from child_process .\n' + data);
    });

    workerProcess.stderr.on('data', function (data) {
        log4jsLogger.info('stderr: ' + data);
    });

    workerProcess.on('close', function (code) {
        log4jsLogger.info('子进程已退出，退出码 '+code);
    });
}

//startProcess() ; //start a process for restore

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(path.dirname(process.argv[1]),conf.static_dir )));
app.use(compression());

app.listen(conf.port,function(){
    console.log('listen '+conf.port);
});
//Global request handler with any request
app.use(function (req, res, next) {
  req.db = db;
  var url = req.url;
  var doNotAuth = ["/userBasicInfo/", "/signin", "/resetpwd", "/signup", "/apiApplication/updateSelfhostIpInfo", "/case", "/enterprise", "/about", "/index", "/opBuildInfo/webhook", "/container_enterprise", "/container_guide", "/container_bigdata", "/container_service", "/apiApplication/autoupd"];

  var auth = {"/userBasicInfo/updateUser": true};
  var noAuth = function (url) {
    for (var index in doNotAuth) {
      if (url.indexOf(doNotAuth[index]) == 0)
        return true;
    }
    return false;
  };
  if (noAuth(url) && !auth[url]) {
    //req.username = req.cookies.username;
    next();
  } else if (req.cookies.token !== undefined) {
    var _token = req.cookies.token;
    try {
      var decoded = _jwt.verify(_token, "we are the biggest secret");
      req.username = decoded.username;
      req.secret = decoded.secret;
      next();
    } catch (err) {
      res.redirect(401, "/signin");
    }

  } else {
    res.redirect(401, "/signin");
  }

});

/*get username
//TODO parse secrect cookie
app.use(function (req, res, next) {
    req.username = req.cookies.username;
    next();
});*/

app.use(require('express-domain-middleware'));

app.use('/api', require('./routes/apiRegistry'));
app.use('/apiV2', require('./routes/apiRegistryV2'));
app.use('/apiKube', require('./routes/apikubeProxy'));
app.use('/opMetaInfo', require('./routes/opMetaInfo'));
app.use('/userBasicInfo', require('./routes/userBasicInfo'));
app.use('/opBuildInfo', require('./routes/opBuildInfo'));
app.use('/apiGit', require('./routes/apiGitRepoInfo'));
app.use('/OauthCallback', require('./routes/opOauth2'));
app.use('/apiDocker', require('./routes/apiDocker'));
app.use('/apiCompose', require('./routes/apiCompose'));
app.use('/apiApplication', require('./routes/apiApplication'));
app.use('/apiMonitor', require('./routes/apiMonitor'));
app.use('/apiStorage', require('./routes/apiStorage'));
app.use('/cluster',require('./routes/apiCluster'));
app.use('/appConfig',require('./routes/appConfig'));
app.use('/trafficRule',require('./routes/trafficRule'));
app.use('/apiLog',require('./routes/apiLog'));

app.use(function errorHandler(err, req, res, next) {

  if (ifGrayUpFilter(req.url)) {
    ///apiApplication/grayudp 比较慢，等完成在返回吧。不处理超时情况了
    return;
  }
  //console.log('error on request %d %s %s: %s', process.domain.id, req.method, req.url, util.inspect(err, {showHidden: false, depth: null}));
  log4jsLogger.error('error on request ' + req.method + " " + req.url + " " + util.inspect(err, {
      showHidden: false,
      depth: null
    }));
  res.status(500).send({
    ret: false,
    error: err.message,
    data: "Something bad happened. :("
  });
});

function ifGrayUpFilter(path) {
  return path && path.indexOf("grayudp") !== -1;
}

//home index
app.get('/',function(req,res){
    res.sendFile(path.join(path.dirname(process.argv[1]),conf.static_dir,conf.indexPage ));
});

//control panel
var cpRouter = express.Router();
cpRouter.get('*', function(req,res){
    res.sendFile(path.join(path.dirname(process.argv[1]),conf.static_dir,conf.dashboardPage));
});
app.use('/cp',cpRouter);

//any other return
app.get('*',function(req,res){
    res.sendFile(path.join(path.dirname(process.argv[1]),conf.static_dir,conf.indexPage ));
});

process.on("uncaughtException", function(err) {
    log4jsLogger.error("[%s] exception happened",err.message);
});

module.exports = app;
exports.logger=function(name){
    var logger = log4js.getLogger(name);
    logger.setLevel('INFO');
    return logger;
}